package com.yfp.goods.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.yfp.common.core.constant.DbConstants;
import com.yfp.common.core.domain.R;
import com.yfp.common.core.exception.ServiceException;
import com.yfp.common.core.utils.bean.BeanUtils;
import com.yfp.common.core.utils.uuid.Snowflake;
import com.yfp.common.datascope.annotation.DataScope;
import com.yfp.common.security.utils.SecurityUtils;
import com.yfp.goods.domain.*;
import com.yfp.goods.domain.dto.ComboDto;
import com.yfp.goods.domain.dto.ComboGroupDTO;
import com.yfp.goods.domain.dto.ComboPlanDto;
import com.yfp.goods.domain.vo.ComboVo;
import com.yfp.goods.enums.PlanTimeEnum;
import com.yfp.goods.mapper.*;
import com.yfp.goods.mapper.*;
import com.yfp.goods.service.ComboService;
import com.yfp.goods.service.ImgResourceService;
import com.yfp.goods.service.TagComboService;
import com.yfp.operation.api.RemoteOperationService;
import com.yfp.goods.domain.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 套餐表(Combo)表服务实现类
 *
 * 
 * @since 2023-12-27 13:33:24
 */
@Slf4j
@Service("comboService")
public class ComboServiceImpl implements ComboService {
    @Resource
    private ComboMapper comboMapper;

    @Resource
    private ComboDetailImgMapper comboDetailImgMapper;

    @Resource
    private CPComboRoadMapper cpComboRoadMapper;

    @Resource
    private ComboGoodsMapper comboGoodsMapper;

    @Resource
    private TagComboService tagComboService;

    @Resource
    private ImgResourceMapper imgResourceMapper;

    @Resource
    private ImgResourceService imgResourceService;


    @Resource
    private ComboPlanMapper comboPlanMapper;

    @Resource
    private RemoteOperationService remoteOperationService;

    /**
     * 通过ID查询单条数据
     *
     * @param comboId 主键
     * @return 实例对象
     */
    @Override
    public Combo queryById(String comboId) {
        Combo combo = this.comboMapper.queryById(comboId);
        String tagId = combo.getTagId();
        if (CharSequenceUtil.isNotEmpty(tagId)) {
            List<String> tagIds = Arrays.stream(tagId.split(",")).toList();
            List<String> tagNames = this.tagComboService.queryByTagIds(tagIds);
            if (CollUtil.isNotEmpty(tagNames)) combo.setTagName(tagNames.toString());
        }
        if (CharSequenceUtil.isNotEmpty(tagId)) {
            TagCombo tagCombo = this.tagComboService.queryById(tagId);
            if (Objects.nonNull(tagCombo)) combo.setTagName(tagCombo.getTagName());
        }
        if (CharSequenceUtil.isNotEmpty(combo.getThumb())) {
            ImgResource imgResource = this.imgResourceMapper.queryById(combo.getThumb());
            if (Objects.nonNull(imgResource)) combo.setThumbUrl(imgResource.getUrl());
        }
        return combo;
    }

    /**
     * 分页查询
     *
     * @param combo 筛选条件
     * @return 查询结果
     */
    @Override
    @DataScope(deptAlias = "c")
    public List<ComboDto> queryAll(Combo combo) {

        List<Combo> combos = this.comboMapper.queryAll(combo);
        return combos.stream().map(combo1 -> {

            ComboDto comboDto = new ComboDto();
            BeanUtil.copyProperties(combo1, comboDto);
            ImgResource imgResource = imgResourceMapper.queryById(combo1.getThumb());
            if (Objects.nonNull(imgResource)) comboDto.setThumb(imgResource.getUrl());
            List<String> tagNames = getTagNames(combo1.getTagId());
            if (CollUtil.isNotEmpty(tagNames)) comboDto.setTagName(tagNames);

            return comboDto;
        }).toList();
    }

    private List<String> getTagNames(String tagId) {
        if (CharSequenceUtil.isNotEmpty(tagId)) {
            List<String> tagIds = Arrays.stream(tagId.split(",")).toList();
            List<String> tagNames = this.tagComboService.queryByTagIds(tagIds);
            if (CollUtil.isNotEmpty(tagNames)) return tagNames;
        }
        return Collections.emptyList();
    }

    /**
     * 新增数据
     *
     * @param combo 实例对象
     * @return 实例对象
     */
    @Override
    public Combo insert(Combo combo) {
        combo.setCompanyId(SecurityUtils.getLoginUser().getCompanyId());
        this.comboMapper.insert(combo);
        return combo;
    }

    /**
     * 修改数据
     *
     * @param combo 实例对象
     * @return 实例对象
     */
    @Override
    public Combo update(Combo combo) {
        this.comboMapper.update(combo);
        return this.queryById(combo.getComboId());
    }

    /**
     * 新增套餐
     *
     * @param comboVo combo vo
     * @return {@link Combo}
     */
    @Override
    public R addCombo(ComboVo comboVo) {
        verifyIfNameIsDuplicated(comboVo);

        Snowflake snowflake = new Snowflake(1);

        Combo combo = new Combo();

        String comboId = String.valueOf(snowflake.nextId());
        BeanUtil.copyProperties(comboVo,combo);
        combo.setComboId(comboId);

        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
        combo.setDeptId(deptId);

        int insert = this.comboMapper.insert(combo);
        if (insert < 1) throw new ServiceException("新增套餐失败");


        List<String> goodsIds = comboVo.getGoodsIds();
        for (String goodsId : goodsIds) {
            String comboGoodsId = String.valueOf(snowflake.nextId());
            ComboGoods comboGoods = new ComboGoods();
            comboGoods.setComboId(comboId);
            comboGoods.setGoodsId(goodsId);
            comboGoods.setComboGoodsId(comboGoodsId);
            comboGoods.setCompanyId(SecurityUtils.getLoginUser().getCompanyId());
            this.comboGoodsMapper.insert(comboGoods);
        }
        List<ComboDetailImg> comboDetailImgList = comboVo.getComboDetailImgList();
        for (ComboDetailImg comboDetailImg : comboDetailImgList) {
            comboDetailImg.setComboId(comboId);
            int insert1 = comboDetailImgMapper.insert(comboDetailImg);
            if (insert1 < 1) throw new ServiceException("新增套餐详情图片失败");
        }

        return R.ok();
    }

    private void verifyIfNameIsDuplicated(ComboVo comboVo) {
        int count = this.comboMapper.countByComboName(comboVo.getName(), comboVo.getComboId(), comboVo.getCityName());
        if (count > 0) throw new ServiceException("套餐名称已存在");
    }

    /**
     * 更新套餐
     *
     * @param comboVo combo vo
     * @return {@link ComboVo}
     */
    @Override
    public ComboVo updateComboVo(ComboVo comboVo) {

        verifyIfNameIsDuplicated(comboVo);
        // 检查套餐是否参与投放
        R<Boolean> booleanR = remoteOperationService.checkComboParticipation(comboVo.getComboId());
        if (R.isError(booleanR)) throw new ServiceException("服务异常");
        if (R.isSuccess(booleanR)) {
            if (booleanR.getData()) {
                throw new ServiceException("存在优惠券关联，不能修改");
            }
        }

        List<ComboDetailImg> comboDetailImgList = comboVo.getComboDetailImgList();

        Combo combo = new Combo();
        combo.setUpdateTime(new Date());
        BeanUtils.copyBeanProp(combo, comboVo);

        int update = this.comboMapper.update(combo);
        if (update < 1) throw new ServiceException("更新套餐失败");

        for (ComboDetailImg comboDetailImg : comboDetailImgList) {
            if (Objects.isNull(comboDetailImg.getId())) {
                this.comboDetailImgMapper.insert(comboDetailImg);
            } else {
                this.comboDetailImgMapper.update(comboDetailImg);
            }
        }
        return comboVo;
    }

    /**
     * 上下架套餐
     *
     * @param comboId 组合id
     * @return boolean
     */
    @Override
    public boolean shelfCombo(String comboId) {
        // TODO是否完成投放计划
        long count = cpComboRoadMapper.queryComboInPlanByComboIds(comboId);
        if (count > 0) throw new ServiceException("该套餐有尚未完成的投放计划");

        Combo combo = this.comboMapper.queryById(comboId);
        if (ObjectUtil.isNull(combo)) return false;
        boolean result = Objects.equals(DbConstants.DISABLED_ABNORMAL, combo.getShelf());

        combo.setShelf(result ? DbConstants.ENABLE_NORMAL : DbConstants.DISABLED_ABNORMAL);
        combo.setUpdateTime(new Date());
        // 套餐下架，团餐自动下架
        combo.setGroupShelf(DbConstants.DISABLED_ABNORMAL);
        return this.comboMapper.update(combo) > 0;
    }

    /**
     * 通过套餐id查询所在投放计划
     *
     * @param comboId 组合id
     * @return {@link List}<{@link ComboPlanDto}>
     */
    @Override
    public List<ComboPlanDto> queryComboPlan(String comboId) {
        List<CPComboRoad> cpComboRoads = cpComboRoadMapper.queryPlanByComboId(comboId);

        if (CollectionUtil.isEmpty(cpComboRoads)) return Collections.emptyList();

        // 按计划id分组
        Map<String, List<CPComboRoad>> planMap = cpComboRoads.stream().collect(Collectors.groupingBy(CPComboRoad::getCPlanId));

        // 收集不重复的计划id
        Set<String> cPlanIds = cpComboRoads.stream().map(CPComboRoad::getCPlanId).collect(Collectors.toSet());

        List<ComboPlanDto> comboPlanDtos = new ArrayList<>();

        for (String cPlanId : cPlanIds) {
            ComboPlan comboPlan = this.comboPlanMapper.queryById(cPlanId);
            log.info("cPlanId:{}", cPlanId);
            log.info("comboPlan:{}", comboPlan);
            if (Objects.isNull(comboPlan)){
                continue;
            }
            // 计划状态
            PlanTimeEnum planTimeEnumByTime = PlanTimeEnum.getPlanTimeEnumByTime(comboPlan.getStartTime(), comboPlan.getEndTime());
            // 已经结束的跳过
            if (Objects.equals(PlanTimeEnum.END.getValue(), planTimeEnumByTime.getValue())) continue;

            ComboPlanDto comboPlanDto = new ComboPlanDto();
            List<CPComboRoad> cpComboRoadsList = planMap.get(cPlanId);

            // 统计总数
            AtomicInteger total = new AtomicInteger();
            cpComboRoadsList.forEach(cpComboRoad -> {

                if (CharSequenceUtil.isNotEmpty(cpComboRoad.getComboNum())) {
                    total.addAndGet(Integer.parseInt(cpComboRoad.getComboNum()));
                }

            });
            comboPlanDto.setNum(total.toString());
            comboPlanDto.setcPlanName(comboPlan.getCPlanName());
            comboPlanDto.setStatus(comboPlan.getStatus());
            comboPlanDto.setcPlanId(cPlanId);
            comboPlanDtos.add(comboPlanDto);
        }
        return comboPlanDtos;
    }

    /**
     * 获取套餐id列表
     *
     * @return
     */
    @Override
    @DataScope(deptAlias = "c")
    public List<Combo> getComboIds(Combo combo) {
        return comboMapper.getComboIds(combo);
    }

    /**
     * 上下架团餐
     *
     * @param comboId
     * @return
     */
    @Override
    public boolean groupShelfCombo(String comboId) {
        Combo combo = this.comboMapper.queryById(comboId);

        if (ObjectUtil.isNull(combo)) return false;
        boolean result = Objects.equals(DbConstants.ENABLE_NORMAL, combo.getGroupShelf());
        if (!result) {
            if (Objects.equals(DbConstants.DISABLED_ABNORMAL, combo.getShelf())) {
                throw new ServiceException("先将该套餐上架之后，才能上架团餐");
            }
        }
        combo.setGroupShelf(result ? DbConstants.DISABLED_ABNORMAL : DbConstants.ENABLE_NORMAL);
        combo.setUpdateTime(new Date());
        return this.comboMapper.update(combo) > 0;
    }

    @Override
    public List<ComboGroupDTO> getGroupShelfComboList() {
        List<Combo> groupShelfComboList = comboMapper.getGroupShelfComboList();
        // 获取图片url地址
        List<String> thumbIds = groupShelfComboList.stream().map(Combo::getThumb).collect(Collectors.toList());
        List<ImgResource> imgResources = imgResourceService.queryByIds(thumbIds);
        Map<String, String> urlMapById = imgResources.stream().collect(Collectors.toMap(ImgResource::getImgId, ImgResource::getUrl, (k1, k2) -> k1));

        List<ComboGroupDTO> collect = BeanUtil.copyToList(groupShelfComboList, ComboGroupDTO.class).stream().peek(item -> {
            item.setThumbUrl(urlMapById.get(item.getThumb()));
        }).collect(Collectors.toList());

        return collect;
    }

    @Override
    public List<Combo> queryByIds(List<String> comboIds) {
        if (CollectionUtil.isEmpty(comboIds)) {
            return List.of();
        }
        List<Combo> combos = comboMapper.queryByIds(comboIds);
        // 获取图片url地址
        List<String> thumbIds = combos.stream().map(Combo::getThumb).collect(Collectors.toList());
        List<ImgResource> imgResources = imgResourceService.queryByIds(thumbIds);
        Map<String, String> urlMapById = imgResources.stream().collect(Collectors.toMap(ImgResource::getImgId, ImgResource::getUrl, (k1, k2) -> k1));

        List<Combo> collect = combos.stream().peek(item -> {
            item.setThumbUrl(urlMapById.get(item.getThumb()));
        }).collect(Collectors.toList());
        return collect;
    }
}
